home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
winsock
/
ircii2-6.zip
/
SRC\IRCII-2.6\SOURCE\FILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-31
|
3KB
|
168 lines
/*
* file.c contains file open/read/write routines to be used to open
* files with the access permissions of the real UID instead of the
* effective UID. This allows IRCII to be run setuid->root. If it
* has effective UID == root, it will then use privileged ports to
* connect to servers, allowing the servers, some day, to take
* advantage of this information to ensure that the user names are
* who they claim to be.
*
* It can also be run setuid->something else, with ircserv being
* setuid->root and only runable by the given GID.
*
* Copyright (c) 1991 Troy Rollo
*
* See HELP IRCII COPYRIGHT for details.
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: file.c,v 1.7 1994/07/02 02:32:13 mrg Stab $";
#endif
#include "irc.h"
#include <sys/stat.h>
#ifdef PRIV_PORT
# undef PRIV_PORT
#endif /* PRIV_PORT */
int directory_writeable(file)
char *file;
{
define_big_buffer(dir);
char *ptr;
int result;
strmcpy(dir, file, BIG_BUFFER_SIZE);
if (ptr = rindex(dir, '/'))
{
if (ptr == dir
#ifdef APOLLO
|| (ptr == dir+1 && *dir == '/')
#endif /*APOLLO*/
)
ptr++;
*ptr = '\0';
}
else
strcpy(dir, ".");
result = (!access(dir, W_OK|X_OK));
free_big_buffer(dir);
return result;
}
int ruid_open(filename, flags, mode)
char *filename;
int flags;
int mode;
{
int access_flags;
int fd;
switch(flags&(O_RDONLY|O_WRONLY|O_RDWR))
{
case O_RDWR:
access_flags = R_OK|W_OK;
break;
case O_RDONLY:
access_flags = R_OK;
break;
case O_WRONLY:
access_flags = W_OK;
break;
}
if (!access(filename, access_flags))
return open(filename, flags, mode);
else if ((flags&O_CREAT) == O_CREAT && directory_writeable(filename))
{
fd = open(filename, flags, mode);
chown(filename, getuid(), getgid());
return fd;
}
else
return -1;
}
FILE *ruid_fopen(filename, mode)
char *filename;
char *mode;
{
int access_flags;
FILE *fp;
char *tm;
access_flags = 0;
for (tm = mode; *tm != '\0'; tm++)
{
switch (*tm)
{
case '+':
access_flags |= W_OK|R_OK;
break;
case 'r':
access_flags |= R_OK;
break;
case 'w':
case 'a':
access_flags |= W_OK;
break;
case 't': /* Text and binary - harmless */
case 'b':
break;
default: /* Calls are guilty unless proven innocent */
return NULL; /* :P to all those who think otherwise! */
}
}
if (!access(filename, access_flags))
return fopen(filename, mode);
else if ((access_flags&W_OK) == W_OK && directory_writeable(filename))
{
fp = fopen(filename, mode);
chown(filename, getuid(), getgid());
return fp;
}
else
return NULL;
}
int ruid_unlink(filename)
char *filename;
{
if (!access(filename, W_OK) && directory_writeable(filename))
unlink(filename);
}
int ruid_system(command)
char *command;
{
int pid;
switch (pid = fork())
{
case 0:
setuid(getuid());
setgid(getgid());
system(command);
_exit(0);
break;
case -1:
return -1;
default:
while(wait(0) != pid);
return 0;
}
}
int ruid_stat(path, buf)
char *path;
struct stat *buf;
{
if (!access(path, 0))
return -1;
else
return stat(path, buf);
}